package cc.linker.steplink.crm.task;


import cc.linker.steplink.crm.commons.lock.RedisLock;
import cc.linker.steplink.crm.dao.CustomerDao;
import cc.linker.steplink.crm.dao.RobotUserPortraitDao;
import cc.linker.steplink.crm.merchant.util.DateUtil;
import cc.linker.steplink.crm.response.GlobalException;
import cc.linker.steplink.crm.service.CustomerService;
import cc.linker.steplink.crm.service.IMarketRobotService;
import cc.linker.steplink.crm.service.ISysConfig;
import com.mongodb.util.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 智能营销机器人推送任务
 */

@Slf4j
@Component
public class MarketRobotTask {


    @Value("${system.scrm.wxpushurl}")
    private String url;

    @Autowired
    private IMarketRobotService marketRobotService;

    @Autowired
    private ISysConfig sysConfigService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private CustomerService customerService;

    @Autowired
    private RobotUserPortraitDao robotUserPortraitDao;

    @Autowired
    private CustomerDao customerDao;

    @Value("wxpushlist_lock")
    private String wxPushPistPockKey;//队列锁键值

    @Value("wxpushlist")
    private String wxPushListKey;//队列键值

    /**
     * 营销组合机器人
     */
    @RedisLock("MarketRobotPush_yx")
    @Scheduled(cron = "1 0/20 * * * ?")
    public void marketRobot() throws Exception {

        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, 1);
        calendar.set(Calendar.DAY_OF_MONTH, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        Date expireDate = calendar.getTime();

        Calendar calendarToday = Calendar.getInstance();
        calendarToday.set(Calendar.HOUR_OF_DAY, 23);
        calendarToday.set(Calendar.MINUTE, 59);
        calendarToday.set(Calendar.SECOND, 59);
        long today = calendarToday.getTimeInMillis() / 1000;


        //当前时间年月日
//        String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy_MM_dd"));

        //获取智能营销机器人开关打开的所有机构id
        Map<String, String> param = new HashMap<>();
        param.put("confName", "marketRobotSwitch");
        param.put("confValue", "1");
        List<Map<String, String>> orgIdList = marketRobotService.getOrgIdByNameAndValue(param);
        if (null != orgIdList && orgIdList.size() > 0) {
            for (Map<String, String> val : orgIdList) {
                //获取机器人配置
                Map<String, Object> orgFunction = customerService.getOrgFunctionOrgId(val.get("orgId"));
                if (orgFunction == null || StringUtils.isEmpty(orgFunction.get("marNum"))) {
                    continue;
                }
                if (!StringUtils.isEmpty(orgFunction.get("marExpireDate"))) {
                    // 判断时间是否到期
                    Long expireTime = dateToStamp(orgFunction.get("marExpireDate").toString() + " 00:00:00");
                    Long nowTime = System.currentTimeMillis();
                    if(nowTime>expireTime){
                        continue;
                    }
                }

                Integer limitNum = 5000 * (Integer.parseInt(orgFunction.get("marNum").toString()));

                String marketRobotStartTime = sysConfigService.getSysConfByName(val.get("orgId"), "marketRobotStartTime");
                if (null == marketRobotStartTime) {
                    marketRobotStartTime = "08:00:00";
                }
                //取当前机构下所有营销组合labelId
                List<Map<String, String>> labelIds = marketRobotService.getlabelIds(val.get("orgId"));
                List<String> artLabel = new ArrayList<>();
                for (Map<String, String> lab : labelIds) {
                    String[] artsplits = lab.get("labelId").split(",");
                    artLabel.addAll(Arrays.asList(artsplits));
                }

                List<Map<String, Object>> userList = customerService.getRobotUserMarket(val.get("orgId"), limitNum);
                for (Map<String, Object> user : userList) {
                    //记录该用户是否被营销过
                    customerService.updateRobotActive(user.get("customerId").toString(), "market");
                    if(StringUtils.isEmpty(user.get("labelId"))){
                        continue;
                    }
                    String lockValue = user.get("token").toString() + user.get("openid").toString();
                    //判断该用户是否在发送队列中
                    Boolean isLock = stringRedisTemplate.opsForSet().isMember(wxPushPistPockKey, lockValue);
                    if (null!=isLock && isLock) {
                        continue;
                    }

                    for (String labelId : artLabel) {
//                        LOGGER.info("market机器人artLabel/artlabelId:" + labelId + ",userlabelId:"+user.get("labelId").toString()+",customerLabelLevel:"+user.get("customerLabelLevel").toString()+"-----market");
                        //当某一个营销组合对于某一个用户大于0分时
                        if (labelId.equals(user.get("labelId").toString()) && !"0".equals(user.get("customerLabelLevel").toString())) {
                            //符合条件，取一篇文章加入发送队列
                            Map<String, String> oneArticle = marketRobotService.getOneArticle(user.get("labelId").toString(), val.get("orgId"), user.get("token").toString(), user.get("openid").toString());
//                            LOGGER.info("market机器人oneArticle:" + oneArticle + "-----market");
                            if (null != oneArticle) {
                                //计算下一次推送时间
                                boolean ifSendToList = true; //是否要放入队列
                                Calendar nextPush = Calendar.getInstance();
                                Map<String, Object> lastPushLog = marketRobotService.getPushLog(user.get("token").toString(), user.get("openid").toString(), "market");
                                if (null != lastPushLog) {
                                    //有推送记录，取最后一次推送记录的阅读时长
                                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                    Date parse = simpleDateFormat.parse(lastPushLog.get("sendTime").toString());
                                    nextPush.setTime(parse);

//                                    String customerId = customerDao.selectCustomerIdByOpenIdAndToken(user.get("openid").toString(), user.get("token").toString());
                                    //获取用户对该文章的阅读时长
                                    Map<String, Object> customerReadTimeParam = new HashMap<>();
                                    customerReadTimeParam.put("articleId", lastPushLog.get("articleId"));
                                    customerReadTimeParam.put("customerId", user.get("customerId").toString());
                                    customerReadTimeParam.put("startTime", DateUtil.dateStr(DateUtil.dateRoler(new Date(), -1)));
                                    customerReadTimeParam.put("endTime", DateUtil.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss"));
                                    int customerReadTime = robotUserPortraitDao.getCustomerReadTime(customerReadTimeParam);

                                    //获取该文章的平均阅读时长
                                    Map<String, Object> articleReadTimeParam = new HashMap<>();
                                    articleReadTimeParam.put("articleId", lastPushLog.get("articleId"));
                                    Integer articleReadTime = robotUserPortraitDao.getArticleReadTime(articleReadTimeParam);

                                    if(StringUtils.isEmpty(articleReadTime)){
                                        articleReadTime = 0;
                                    }
//                                    LOGGER.info("market机器人customerReadTime=" + customerReadTime + ",articleReadTime="+articleReadTime+"-----market,openid="+user.get("openid")+",token="+user.get("token"));
//                                    if (customerReadTime < (0.5 * articleReadTime)) {
//                                        ifSendToList = false;
//                                    }
                                    nextPush.add(Calendar.DAY_OF_MONTH, Integer.parseInt(user.get("customerPushrateLevel").toString()));
                                }else{
                                    //没有推送记录
                                    String[] split = marketRobotStartTime.split(":");
                                    if (split.length != 3) {
                                        throw GlobalException.build("时间不对");
                                    }
                                    nextPush.set(Calendar.HOUR_OF_DAY, Integer.valueOf(split[0]));
                                    nextPush.set(Calendar.MINUTE, Integer.valueOf(split[1]));
                                    nextPush.set(Calendar.SECOND, Integer.valueOf(split[2]));
                                }
                                Date time = nextPush.getTime();
                                long nextPushTime = time.getTime() / 1000;

                                if(ifSendToList && (today > nextPushTime)){
                                    Map<String, Object> pushData = new HashMap<>();
                                    pushData.put("token", user.get("token"));
                                    pushData.put("openid", user.get("openid"));
                                    pushData.put("title", oneArticle.get("articleTitle"));
                                    pushData.put("desc", oneArticle.get("articleDesc"));
                                    pushData.put("url", oneArticle.get("articleUrl"));
                                    pushData.put("image", oneArticle.get("articleImage"));
                                    pushData.put("articleId", oneArticle.get("articleId"));
                                    pushData.put("orgId", oneArticle.get("orgId"));
                                    pushData.put("time", nextPushTime);
                                    pushData.put("type", "market");
                                    stringRedisTemplate.opsForSet().add(wxPushListKey, JSON.serialize(pushData));
                                    stringRedisTemplate.expireAt(wxPushListKey, expireDate);
                                    stringRedisTemplate.opsForSet().add(wxPushPistPockKey, lockValue);
                                    stringRedisTemplate.expireAt(wxPushPistPockKey, expireDate);
                                }

                            }
                        }
                    }
                }
            }
        }
    }
    /*
     * 将时间转换为时间戳
     */
    public static Long dateToStamp(String s) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = simpleDateFormat.parse(s);
        return  date.getTime();
    }

}
